package com.dingding.order.core.syncorder.biz.impl;

import java.math.BigDecimal;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.beans.SyncOrder;
import com.dingding.common.core.message.shotmsg.ShotMessageBuilder;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.GetDistanceUtil;
import com.dingding.common.core.util.JSONUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.amap.AmapApi;
import com.dingding.common.core.util.dto.CalculatDistanceDTO;
import com.dingding.facade.queue.dto.msg.MessageRequestsDTO;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.facade.user.facade.userlogin.IUserLoginFacade;
import com.dingding.order.code.order.PublishOrderEnum;
import com.dingding.order.core.distance.biz.ICalculateDistanceService;
import com.dingding.order.core.publish.biz.IPublishOrderService;
import com.dingding.order.core.syncorder.biz.ISyncOrderService;
import com.dingding.order.core.syncorder.dao.ISyncOrderDao;
import com.dingding.order.dto.distance.ReqCalculateDistanceDTO;
import com.dingding.order.dto.publish.ReqReleaseOrderDTO;

/**
 * 
 * 此类主要用来同步第三方网站订单数据到叮叮平台上
 * 
 * @ClassName: SyncOrderImpl
 * @Description: 订单同步业务
 * @author CHEHAUNBO
 * @date 2016年7月26日 上午11:00:49
 * 
 * 
 */
@Component("syncOrderService")
public class SyncOrderServiceImpl implements ISyncOrderService {

	private Logger log = Logger.getLogger(this.getClass());

	/**
	 * 用户登录服务
	 */
	@Resource(name = "userLoginFacadeV2")
	private IUserLoginFacade userLoginFacade;

	/**
	 * 发布订单业务
	 */
	@Resource(name = "publishOrderService")
	private IPublishOrderService publishOrderService;

	/**
	 * 订单同步Dao
	 */
	@Resource(name = "syncOrderDao")
	private ISyncOrderDao syncOrderDao;
	
	/**
	 * 计算距离service
	 */
	@Resource(name = "distanceService")
	private ICalculateDistanceService distanceService;


	/**
	 * 短信推送
	 */
	@Resource(name = "queueService")
	private IQueueFacade queueFacade;
	
	/**
	 * 
	 * 同步订单
	 * 
	 * 此方法主要用来同步从地方网站获取的订单数据到叮叮平台中
	 * 
	 * @Title: syncOrder
	 * @author CHEHAUNBO
	 * @since V2.3.2
	 * 
	 * 
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void syncOrder() {

		// 1.获取待同步的订单
		List<SyncOrder> syncOrders = syncOrderDao.getAllSyncOrder();

		if (syncOrders == null || syncOrders.size() <= 0) {
			return;
		}

		for (SyncOrder order : syncOrders) {

			// 2.注册用户
			boolean regStat = this.userLoginFacade.userRegister(order.getTelPhone());
			if (regStat == false) {
				log.error("同步订单业务，注册用户时失败!SyncOrderServiceImpl:syncOrder()");
				continue;
			}
			
			// 3.根据车主发单还是乘客发单改变用户的角色
			boolean changeStat = this.userLoginFacade.changeSyncorderPublisherRole(order.getPublisherType(), order.getTelPhone());
			if(changeStat == false){
				log.error("改变用户角色时失败！SyncOrderServiceImpl:syncOrder()");
				continue;
			}
			
			// 4.完善发单信息
			ReqReleaseOrderDTO request = this.completeOrder(order);
			if (request == null) {
				order.setIsPublished(2); // 如果完善订单信息出错说明该订单不可用
				continue;
			}
			
			// 5.发单
			if (this.publishOrder(request)) {
				order.setIsPublished(1);
			}else{
				continue;
			}
			
			// 6.给用户发送短信提示下载叮叮搭车
			sendMessage(order.getTelPhone());
		}
	}

	/**
	 * @Description: 完善发单信息
	 * @author fengshuonan
	 * @return ReqReleaseOrderDTO 完整的发单信息
	 * @since 2.3.2
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	private ReqReleaseOrderDTO completeOrder(SyncOrder syncOrder) {

		ReqReleaseOrderDTO request = new ReqReleaseOrderDTO();

		// 设置用户角色
		request.setUserType(syncOrder.getPublisherType());

		// 设置下单用户的id
		String userId = this.userLoginFacade.getUserIdByTell(syncOrder.getTelPhone());
		if (ToolUtil.isBlank(userId)) {
			log.error("同步订单业务，完善订单时，通过手机号获取用户id出错!SyncOrderServiceImpl:syncOrder()");
			return null;
		}
		request.setPlaceOrderUserId(userId);

		// 设置下单城市
		if (ToolUtil.isBlank(syncOrder.getPlaceOrderCity())) {
			String payCity = AmapApi.getCityName(syncOrder.getStartAddress());
			if (ToolUtil.isBlank(payCity)) {
				return null;
			}
			request.setPayCity(payCity);
		} else {
			request.setPayCity(syncOrder.getPlaceOrderCity());
		}

		// 设置出发时间
		request.setSetOutTime(DateFormatUtil.yyyy_MM_dd_HHmmss(syncOrder.getSetOutTime()));

		// 设置出发地，目的地
		request.setStartAddress(syncOrder.getStartAddress());
		request.setEndAddress(syncOrder.getEndAddress());
		
		// 设置出发地经纬度
		String slnglat = AmapApi.getLngLatNumString(syncOrder.getStartAddress());
		if(ToolUtil.isBlank(slnglat)){
			return null;
		}
		request.setStartLongitude(AmapApi.getLongitude(slnglat));
		request.setStartLatitude(AmapApi.getLatitude(slnglat));
		
		// 设置目的地经纬度
		String elnglat = AmapApi.getLngLatNumString(syncOrder.getEndAddress());
		if(ToolUtil.isBlank(elnglat)){
			return null;
		}
		request.setEndLongitude(AmapApi.getLongitude(elnglat));
		request.setEndLatitude(AmapApi.getLatitude(elnglat));
		
		//设置两点距离
		BigDecimal distance = syncOrder.getDistance();
		if(distance == null || distance.compareTo(new BigDecimal(0)) == 0){
			CalculatDistanceDTO dto = GetDistanceUtil.getSingleDistance(
					request.getStartLongitude(), request.getStartLatitude(),
					request.getEndLongitude(), request.getEndLatitude());
			if(dto != null){
				request.setDistance(dto.getDistance());
			}else{
				return null;
			}
		}else{
			request.setDistance(distance);
		}
		
		//设置里程费用
		BigDecimal cost = syncOrder.getTotalMoney();
		if(cost == null || cost.compareTo(new BigDecimal(0)) == 0){
			ReqCalculateDistanceDTO dto = new ReqCalculateDistanceDTO(
					request.getPlaceOrderUserId(),request.getStartLatitude(),request.getStartLongitude(),
					request.getEndLatitude(),request.getEndLongitude(),syncOrder.getPublisherType());
			cost = this.distanceService.calcDistanceCost(dto);
			if(cost == null){
				return null;
			}
		}
		request.setOrderCost(cost);
		
		//设置人数
		if(syncOrder.getNumber() == null || syncOrder.getNumber() == 0){
			request.setNumber(1);//默认1人
		}else{
			request.setNumber(syncOrder.getNumber());
		}
		
		//设置是否合乘
		if(syncOrder.getIsCarShare() == null || syncOrder.getIsCarShare() == 0){
			request.setIsCarShare(2);//默认不合乘
		}else{
			request.setIsCarShare(syncOrder.getIsCarShare());
		}
		
		//设置是否长途单
		request.setIsLongDistance(1);//非长途
		
		//设置出发条件 1：准时出发 2：出发前后10分钟
		request.setSetOutCondition(2);
		
		return request;
	}

	/**
	 * @Description:发布订单
	 * @author fengshuonan
	 * @since 2.3.2
	 */
	private boolean publishOrder(ReqReleaseOrderDTO request) {

		PublishOrderEnum enumm = this.publishOrderService.makeAnOrder(request);

		if (enumm.equals(PublishOrderEnum.OK)) {
			return true;
		}

		log.error("发单不成功！原因是：" + enumm.getMessage());
		return false;
	}
	
	/**
	 * @Description:给用户推送短信
	 * @author fengshuonan
	 * @since 2.3.2
	 */
	private void sendMessage(String tellphone){
		MessageRequestsDTO messageRequestsDTO = new MessageRequestsDTO();
		messageRequestsDTO.setTelPhone(tellphone);
		messageRequestsDTO.setMessageContent(ShotMessageBuilder.SYNC_ORDER_PUBLISH);
		this.queueFacade.addMessageToQueue(JSONUtil.toJSONString(messageRequestsDTO));
	}

}
